Transacciones – Referencia del Go SDK
Descripción general
El Go SDK expone un pequeño conjunto de tipos y métodos para:
- Cargar un wallet
- Abrir una sesión de transaction contra un node
- Construir, firmar y enviar una transaction
- Inspeccionar la transaction resultante y su estado
Esta página documenta esos tipos y métodos principales como referencia rápida. Los tutoriales y ejemplos de extremo a extremo se encuentran en páginas separadas.
Imports
import (
"github.com/ULedgerInc/go-sdk/pkg/wallet"
"github.com/ULedgerInc/go-sdk/pkg/transaction"
)
Carga del wallet
wallet.FromJson
func FromJson(raw string, passphrase string) (UL_Wallet, error)
Carga un wallet cifrado o en texto plano desde una cadena JSON y devuelve una instancia de UL_Wallet, que luego se utiliza para firmar transactions.
Uso en tu CLI:
w, err := wallet.FromJson(rawWallet, passphrase)
if err != nil {
return fmt.Errorf("error loading wallet: %w", err)
}
fmt.Printf("Loaded wallet: %+v\n", w)
El UL_Wallet devuelto expone:
Address– la dirección del walletGetKey()– devuelve la clave subyacente, utilizada para firmar compromisos y descubrir elKeyType.
Sesión de transaction
Tipo: UL_TransactionSession
type UL_TransactionSession struct {
nodeEndpoint string
suggestor string
wallet wallet.UL_Wallet
}
Una sesión de transaction encapsula:
- El node endpoint (URL base del node)
- El suggestor (ID del node utilizado para la transaction)
- El wallet usado para firmar la transaction
Normalmente se obtiene mediante el constructor:
transaction.NewUL_TransactionSession
func NewUL_TransactionSession(
nodeEndpoint string,
wallet wallet.UL_Wallet,
) (UL_TransactionSession, error)
Lo que hace:
- Llama a
GET {nodeEndpoint}/healthpara obtener los metadatos del node (nodeId, versión, información de chains). - Llama a
GET {nodeEndpoint}/blockchainspara asegurarse de que al menos un blockchain esté disponible. - Devuelve un
UL_TransactionSessioncon:nodeEndpointconfiguradosuggestorconfigurado con el ID del nodewalletconfigurado con elUL_Walletproporcionado
Ejemplo:
session, err := transaction.NewUL_TransactionSession(
testConfig.NodeEndpoints[n],
*wallet,
)
if err != nil {
return fmt.Errorf("error creating transaction session: %w", err)
}
(*UL_TransactionSession).GenerateTransaction
func (session *UL_TransactionSession) GenerateTransaction(
input ULTransactionInput,
) (ULTransaction, error)
Responsabilidades de alto nivel:
-
Rellenar metadatos en
ULTransactionInput:- Establece
input.Suggestorconsession.suggestor - Establece
input.SenderTimestampcon la hora UTC actual - Para payloads que no sean
CREATE_WALLETniALTER_WALLET, estableceinput.Fromconsession.wallet.Address - Establece
input.KeyTypebasándose ensession.wallet.GetKey().GetType()
- Establece
-
Calcular el compromiso y el payload root:
-
Para
DEPLOY_SMART_CONTRACT,UPGRADE_SMART_CONTRACT,TX_CREATE_WALLET,TX_ALTER_WALLET:- Llama a
input.GetUnboundCommitment(hasher) - Establece
input.PayloadRootcon el root devuelto (codificado en hex)
- Llama a
-
Para otros tipos de transaction:
- Llama a
input.GetSignatureCommitment(hasher, true)para construir un compromiso Merkle - Llama a
input.HashSignatureCommitment(hasher, commitment)para obtener el hash del compromiso - Establece
input.PayloadRootcon el Merkle payload root
- Llama a
-
-
Firmar el compromiso:
- Firma el compromiso con
session.wallet.GetKey().SignData(commitment) - Establece
input.SenderSignaturecon la firma codificada en hex
- Firma el compromiso con
-
Enviar al node:
-
Envía JSON mediante POST a:
POST {nodeEndpoint}/blockchains/{blockchainId}/transactions -
Espera
200 OKo201 Created -
Deserializa la respuesta en un
ULTransaction
-
Ejemplo:
tx, err := session.GenerateTransaction(input)
if err != nil {
return fmt.Errorf("error generating transaction: %w", err)
}
if tx.TransactionId == "" {
return fmt.Errorf("generated transaction has empty transaction ID")
}
fmt.Printf("Transaction: %+v\n", tx)
Tipos de transaction
ULTransactionInput
Campos utilizados para crear una transaction:
type ULTransactionInput struct {
BlockchainId string `json:"blockchainId"`
To string `json:"to"`
From string `json:"from"`
Payload string `json:"payload"`
SenderSignature string `json:"senderSignature"`
PayloadType string `json:"payloadType"`
Suggestor string `json:"suggestor"`
SenderTimestamp time.Time `json:"senderTimestamp"`
PayloadRoot string `json:"payloadRoot"`
KeyType crypto.KeyType `json:"keyType"`
}
Uso típico para una transaction de tipo DATA:
input := transaction.ULTransactionInput{
Payload: fmt.Sprintf("test %v %d", wallet.Address, n*i),
From: wallet.Address, // overridden by session for most types
To: wallet.Address,
BlockchainId: blockchainId,
PayloadType: transaction.TX_DATA.String(),
}
La mayoría de los campos son rellenados por GenerateTransaction (firma, marcas de tiempo, suggestor, tipo de clave y PayloadRoot).
ULTransactionOutput
Campos devueltos por el node:
type ULTransactionOutput struct {
TransactionId string `json:"transactionId"`
BlockHeight int `json:"blockHeight"`
Clock VectorClock `json:"vectorClock"`
Timestamp Timestamp `json:"timestamp"`
Version string `json:"version"`
Weight int `json:"weight"`
Status string `json:"status"`
Output string `json:"output"`
Proof string `json:"proof"`
ProofVersion string `json:"proofVersion"`
}
ULTransaction
type ULTransaction struct {
ULTransactionInput
ULTransactionOutput
}
Combina tanto los campos de input (lo que solicitaste) como los campos de output (lo que devolvió el node).
Helpers e interfaces de transaction
Interfaz Transaction
type Transaction interface {
GetVectorClock() VectorClock
GetTimestamp() Timestamp
GetTransactionId() string
GetTransactionSignatureBody() string
SetTransactionWeight()
}
ULTransaction implementa esta interfaz (excepto GetTransactionSignatureBody, que no se muestra en el fragmento proporcionado pero forma parte del contrato conceptual).
Métodos en *ULTransaction
func (t *ULTransaction) GetVectorClock() VectorClock
func (t *ULTransaction) GetTimestamp() Timestamp
func (t *ULTransaction) GetTransactionId() string
func (t *ULTransaction) SetTransactionWeight()
func (t *ULTransaction) ToBytes() ([]byte, error)
GetVectorClock()– devuelve el reloj vectorial causal para esta transaction.GetTimestamp()– devuelve la estructuraTimestamp(tiempos exactos y aproximados).GetTransactionId()– devuelve el ID de transaction asignado por el node.SetTransactionWeight()– recalcula y establecet.Weightbasándose en las longitudes de los campos.ToBytes()– serializa la transaction a bytes JSON.
TransactionFromBytes
func TransactionFromBytes(data []byte) (*ULTransaction, error)
Deserializa un slice de bytes JSON en un ULTransaction.
Enums y helpers de análisis de transactions
Estado: UL_TransactionStatus
type UL_TransactionStatus int
const (
INVALID_TX_STATUS UL_TransactionStatus = 0
TX_SUBMITTED UL_TransactionStatus = 1
TX_ACCEPTED UL_TransactionStatus = 2
TX_REJECTED UL_TransactionStatus = 3
)
func (ts UL_TransactionStatus) String() string
func ParseTransactionStatus(str string) (UL_TransactionStatus, error)
Tipo: ULTransactionType
type ULTransactionType int
const (
INVALID_TX_TYPE ULTransactionType = iota
TX_DATA
TX_CREATE_WALLET
TX_ALTER_WALLET
DEPLOY_SMART_CONTRACT
INVOKE_SMART_CONTRACT
UPGRADE_SMART_CONTRACT
ROLLBACK_SMART_CONTRACT
)
func (tt ULTransactionType) String() string
func ParseTransactionType(str string) (ULTransactionType, error)
Valores comunes:
TX_DATA– transaction de datos genéricaTX_CREATE_WALLET/TX_ALTER_WALLET– transactions de gestión de walletDEPLOY_SMART_CONTRACT,INVOKE_SMART_CONTRACT,UPGRADE_SMART_CONTRACT,ROLLBACK_SMART_CONTRACT– operaciones de smart contract
Output: UL_TransactionOutput
type UL_TransactionOutput int
const (
INVALID_TX_OUTPUT UL_TransactionOutput = 0
TO_BE_PROCESSED UL_TransactionOutput = 1
TX_SUCCESS UL_TransactionOutput = 2
TX_REJECTED_BY_DUPLICATE UL_TransactionOutput = 3
TX_REJECTED_BY_UNEXISTING UL_TransactionOutput = 4
TX_REJECTED_BY_DISABLED UL_TransactionOutput = 5
TX_REJECTED_BY_UNAUTHORIZED UL_TransactionOutput = 6
TX_REJECTED_BY_INVALID_SIGNATURE UL_TransactionOutput = 7
TX_TRANSACTION_ERROR UL_TransactionOutput = 8
)
func (tt UL_TransactionOutput) String() string
func ParseTransactionOutput(str string) (UL_TransactionOutput, error)
Estos valores corresponden al campo de cadena Output devuelto en ULTransactionOutput.Output.
Compromisos y árboles Merkle (avanzado)
Para casos de uso avanzados donde se necesita control manual sobre los compromisos o la verificación, el SDK expone helpers en ULTransactionInput y constructores de árboles Merkle.
Helpers de compromiso en *ULTransactionInput
func (t *ULTransactionInput) GetSignatureCommitment(
hasher hash.Hash,
computeRoot bool,
) (TransactionCommitment, error)
func (t *ULTransactionInput) GetUnboundCommitment(
hasher hash.Hash,
) ([]byte, error)
func (t *ULTransactionInput) HashSignatureCommitment(
hasher hash.Hash,
commitment TransactionCommitment,
) ([]byte, error)
Utilizados internamente por GenerateTransaction para:
- Construir raíces Merkle sobre el payload
- Vincular
BlockchainId,From,To,Suggestor, la marca de tiempo y el payload root en un único hash de compromiso - Producir los datos que finalmente son firmados por la clave del wallet
Helpers de Merkle
func GenerateMerkleTreeWithHardBound(
payload []byte,
modulus *big.Int,
chunkSize int,
depth int,
hasher hash.Hash,
proofIndex uint64,
) ([]byte, [][]byte, []byte, uint64, error)
func GenerateMerkleTree(
payload []byte,
modulus *big.Int,
chunkSize int,
hasher hash.Hash,
proofIndex uint64,
) ([]byte, [][]byte, []byte, uint64, int, error)
Estas funciones:
- Dividen el payload en fragmentos
- Construyen un árbol Merkle
- Devuelven:
- La raíz Merkle
- Los elementos de prueba
- El fragmento utilizado para las pruebas
- El número de hojas
- (para
GenerateMerkleTree) la profundidad del árbol
Payloads de smart contract y serializador
Además de los payloads estándar de tipo TX_DATA, el SDK también expone tipos y helpers dedicados para interactuar con smart contracts, lo que permite modelar llamadas a contratos, actualizaciones y rollbacks como payloads JSON que pueden enviarse a través del mismo flujo de transaction.
Estructuras de payload de contrato
type ContractArgs struct {
Value []byte `json:"value"`
}
type InvokeContractPayload struct {
FunctionName string `json:"functionName"`
Args []ContractArgs `json:"args"`
GasLimit uint64 `json:"gasLimit"`
}
type RollbackContractPayload struct {
TargetVersion uint64 `json:"targetVersion"`
RollbackReason string `json:"rollbackReason,omitempty"`
}
type UpgradeContractPayload struct {
NewSourceCode string `json:"newSourceCode"`
UpgradeReason string `json:"upgradeReason,omitempty"`
}
Estas estructuras deben ser codificadas en JSON y colocadas en ULTransactionInput.Payload cuando:
PayloadType == INVOKE_SMART_CONTRACT.String()PayloadType == UPGRADE_SMART_CONTRACT.String()PayloadType == ROLLBACK_SMART_CONTRACT.String()
Serializador de la VM del contrato
El serializador codifica valores de Go en el formato binario esperado por la VM de smart contracts de ULedger.
type ContractDataType byte
const (
TypeNull ContractDataType = 0
TypeBool ContractDataType = 1
TypeInt32 ContractDataType = 2
TypeInt64 ContractDataType = 3
TypeString ContractDataType = 4
TypeBytes ContractDataType = 5
TypeArray ContractDataType = 6
TypeMap ContractDataType = 7
TypeFloat32 ContractDataType = 8
TypeFloat64 ContractDataType = 9
)
func Encode(data interface{}) ([]byte, error)
func Decode(data []byte) (interface{}, error)
func GetType(data []byte) (ContractDataType, error)
A alto nivel:
Encode– toma valores de Go (bool,int32,string,[]byte,map[string]interface{},[]interface{}, etc.) y devuelve un blob binario para la VM.Decode– invierte ese proceso (principalmente útil para herramientas, pruebas o decodificación fuera de la cadena).GetType– inspecciona el primer byte y devuelve elContractDataTypecodificado.
Estas herramientas se utilizan principalmente al construir los argumentos para llamadas a smart contracts y se tratarán con mayor profundidad en una guía dedicada a "Smart contracts".
Esta página está pensada como una referencia. Para guías paso a paso, consulta nuestra sección de tutoriales.